/*
 * @Description: 原文检测 - 可用性检测
 * @Author: Rfan
 * @Date: 2022-10-10 14:19:09
 * @LastEditTime: 2022-10-21 18:11:53
 */

import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { Button, Checkbox, Col, Row, Space, Typography } from 'antd';
import cs from 'classnames';
import classnames from 'classnames/bind';
import { editItemById, insertItem, selectItemByKey } from '@/utils/list';
import { CheckProps, EnumUsabilityRuleType } from '../../../../../../dictionaries';
import type { IPropsRule } from '../../../../../../interface';
import styles from '../../../styles/entryPanes.module.scss';
import mainStyles from '../../../styles/main.module.scss';
import { isNullObj } from '@/utils';
import { useAddPlanDialogContext } from '@/view/system/ArchivesDetection/components/dialogs/AddPlan/contexts/AddPlanDialogContext';

const cx = classnames.bind(styles);
const mainCx = classnames.bind(mainStyles);

const extList = [
  'pdf',
  'ofd',
  'xls',
  'xlsx',
  'doc',
  'docx',
  'txt',
  'rtf',
  'wps',
  'gif',
  'png',
  'jpg',
  'jpeg',
  'svg',
  'mp3',
  'wav',
  'ogg',
  'mp4',
  'mkv',
  'flv',
  'avi'
];

// 可用性字段规则类型
export interface IUsabilityFieldRules {
  ruleType: EnumUsabilityRuleType.OriginalFormat;
  ruleValid: Boolean;
  rules: string[];
}

// 条目可用性规则列表类型
type OriAuthRules = (IUsabilityFieldRules | IPropsRule<EnumUsabilityRuleType>)[];

// 条目可用性完整类型
export interface IUsabilityFullRules {
  ruleType: CheckProps.Usability;
  rules: OriAuthRules;
}

const EntryUsabilityCheck = (props: any, ref: any) => {
  const { currentRuleInfo, getPropertyRules } = useAddPlanDialogContext();
  const [ruleList, setRuleList] = useState<OriAuthRules>([]);

  useImperativeHandle(ref, () => ({
    save: () => {
      const fullRules: IUsabilityFullRules = {
        ruleType: CheckProps.Usability,
        rules: ruleList
      };
      return fullRules;
    }
  }));

  /**
   * @description: 获取到规则后回写
   */
  useEffect(() => {
    if (currentRuleInfo && !isNullObj(currentRuleInfo)) {
      const ruleObj = getPropertyRules(CheckProps.Usability);
      setRuleList(ruleObj?.rules || []);
    }
  }, [currentRuleInfo]);

  /**
   * @description: 获取规则选中状态
   * @return {string[]} 选中状态
   */
  const getExtState = (): string[] => {
    const type = EnumUsabilityRuleType.OriginalFormat;
    const currentRule = selectItemByKey(type, ruleList, 'ruleType');
    return currentRule?.rules || [];
  };

  /**
   * @description: 选择检测的扩展名
   * @param {string} values
   */
  const changeExt = (values: string[]) => {
    const type = EnumUsabilityRuleType.OriginalFormat;
    const currentRule = selectItemByKey(type, ruleList, 'ruleType');
    const editRule = currentRule
      ? editItemById(
          type,
          { ...currentRule, ruleValid: values.length > 0, rules: values },
          ruleList,
          'ruleType'
        )
      : insertItem({ ruleType: type, ruleValid: values.length > 0, rules: values }, ruleList);
    setRuleList(editRule);
  };

  /**
   * @description: 全选扩展名
   */
  const selectAllExt = () => {
    changeExt(extList);
  };

  /**
   * @description: 反选扩展名
   */
  const selectInverseExt = () => {
    const type = EnumUsabilityRuleType.OriginalFormat;
    const currentRule = selectItemByKey(type, ruleList, 'ruleType');
    if (currentRule) {
      const selectExts = currentRule.rules || [];
      changeExt(extList.filter((ext) => selectExts.indexOf(ext) < 0));
    } else {
      selectAllExt();
    }
  };

  /**
   * @description: 获取规则选中状态
   * @param {EnumUsabilityRuleType} type 可用性检测类型
   * @return {boolean} 选中状态
   */
  const getRuleState = (type: EnumUsabilityRuleType): boolean => {
    const currentRule = selectItemByKey(type, ruleList, 'ruleType');
    return currentRule?.ruleValid;
  };

  /**
   * @description: 设置规则选中状态
   * @param {boolean} valid 选中状态
   * @param {EnumUsabilityRuleType} type 可用性检测类型
   */
  const setRuleState = (valid: boolean, type: EnumUsabilityRuleType) => {
    const currentRule = selectItemByKey(type, ruleList, 'ruleType');
    const editRule = currentRule
      ? editItemById(type, { ...currentRule, ruleValid: valid }, ruleList, 'ruleType')
      : insertItem({ ruleType: type, ruleValid: valid }, ruleList);
    setRuleList(editRule);
  };

  return (
    <>
      <div className={cs(mainCx('property-wrap'), cx('property-usability'))}>
        <Space className={mainCx('property--title-wrap')} align="center">
          <Space>
            <h6 className={mainCx('property--title')}>电子原文检测</h6>
            <Typography.Text type="secondary">检测原文格式需满足以下选择的格式范围</Typography.Text>
          </Space>

          <div className={mainCx('select-btn')}>
            <Button
              type="text"
              size="small"
              onClick={() => {
                selectAllExt();
              }}
            >
              全选
            </Button>{' '}
            /{' '}
            <Button
              type="text"
              size="small"
              onClick={() => {
                selectInverseExt();
              }}
            >
              反选
            </Button>
          </div>
        </Space>
        <Row>
          <Col span={18}>
            <Checkbox.Group value={getExtState()} onChange={changeExt}>
              <Space size="large" wrap>
                {extList.map((ext: string) => (
                  <Checkbox key={ext} value={ext}>
                    {ext}
                  </Checkbox>
                ))}
              </Space>
            </Checkbox.Group>
          </Col>
        </Row>
      </div>
      <div className={cs(mainCx('property-wrap'), cx('property-usability'))}>
        <Space direction="vertical">
          <Checkbox
            checked={getRuleState(EnumUsabilityRuleType.OriginalContentReadability)}
            onChange={(evt) => {
              setRuleState(evt.target.checked, EnumUsabilityRuleType.OriginalContentReadability);
            }}
          >
            内容数据的可读性检测（保证特定格式的电子档案内容数据可读）
          </Checkbox>
          <Checkbox
            checked={getRuleState(EnumUsabilityRuleType.OriginalEnvironmentCompliance)}
            onChange={(evt) => {
              setRuleState(evt.target.checked, EnumUsabilityRuleType.OriginalEnvironmentCompliance);
            }}
          >
            软硬件环境合规性检测(对电子属性信息中记录的软硬件环境信息进行检测，判断其是否符合归档/移交要求)
          </Checkbox>
          <Checkbox
            checked={getRuleState(EnumUsabilityRuleType.OriginalEnvironmentalChange)}
            onChange={(evt) => {
              setRuleState(evt.target.checked, EnumUsabilityRuleType.OriginalEnvironmentalChange);
            }}
          >
            保存环境变化情况检测（依据电子档案属性信息中记录的系统环境信息对长期保存的软硬件环境信息进行检测，判断长期保存环境的变化情况）
          </Checkbox>
        </Space>
      </div>
    </>
  );
};

export default forwardRef(EntryUsabilityCheck);
